/*
 Copyright (c) 2013 MeherTJ G. All rights reserved.
 License: LGPL for personnal study or free software.
 */

#pragma once

#include "zen_app.h"

#if ZEN_OS_IOS

#include "zen_log.h"

@protocol ViewCtrl

- (void)onFPSChange;
- (void)onStatusVisibleChange;
- (void)onMultiTouchChange;
- (void)onRotatableChange;

@end

class AppIOS : public Zen::App
{
protected:
	std::shared_ptr<Zen::AppDelegate> m_delegate = nullptr;
	
	Zen::P2i mSize;
	
	bool m_rotatable = true;
	
	bool m_status_visible = false;
	
	bool m_is_paused = false;

	bool m_is_multi_touch = true;

	int m_low_frame_rate = 0;
	int m_draw_jump = 0;

	float m_fps = 60.f;

	id <ViewCtrl> m_view_ctrl;
public:
	static std::shared_ptr<AppIOS> Instance();

	void InitializeDelegate(id <ViewCtrl> vc)
	{
		m_view_ctrl = vc;
		m_delegate = ZenAppDelegateCreate();
	}

	virtual void Terminate() override
	{
		this->stop();
		::exit(0);
	}

	virtual std::shared_ptr<Zen::AppDelegate>
	GetRuntimeDelegate() override
	{
		return m_delegate;
	}
	
	virtual float GetFramesPerSecond() override
	{
		return m_fps;
	}
	virtual void SetFramesPerSecond(float frames) override
	{
		m_fps = frames;
		if(m_view_ctrl)
		{
			[m_view_ctrl onFPSChange];
		}
	}
	
	virtual bool IsMultiTouchEnabled() override
	{
		return m_is_multi_touch;
	}
	virtual void SetMultiTouchEnabled(bool use) override
	{
		m_is_multi_touch = use;
		if(m_view_ctrl)
		{
			[m_view_ctrl onMultiTouchChange];
		}
	}
	
	virtual bool IsRotatable() override
	{
		return m_rotatable;
	}
	virtual void SetRotatable(bool flag) override
	{
		m_rotatable = flag;

		if(m_view_ctrl)
		{
			[m_view_ctrl onRotatableChange];
		}
	}
	
	virtual bool IsStatusVisible() override
	{
		return m_status_visible;
	}
	virtual void SetStatusVisible(bool show) override
	{
		m_status_visible = show;
		if(m_view_ctrl)
		{
			[m_view_ctrl onStatusVisibleChange];
		}
	}
	
	bool IsBGUpdate() override {
		return false;
	}
	
	void SetBGUpdate(bool v) override {
		if(v) Zen::LogD("BGUpdate not supported on iOS");
	}

	void SetLowFrameRate(int jump) override {
		m_low_frame_rate = jump;
	}

	int GetLowFrameRate() override {
		return m_low_frame_rate;
	}


public:
	void Update();
	
	void draw();
	
	void launch(Zen::P2i view_size);
	
	void resize(Zen::P2i view_size);
	
	void stop();
	
	void pause();
	
	void resume();
	
	void touchDown(Zen::AppTouch);
	
	void touchUp(Zen::AppTouch);
	
	void touchCancel(Zen::AppTouch);
	
	void touchMove(Zen::AppTouch);
	
	AppIOS()
	{
		m_delegate = nullptr;
	}
};


inline void AppIOS::Update()
{
	m_delegate->OnUpdate();
}

inline void AppIOS::draw()
{
	if(0 == m_low_frame_rate)
	{
		m_delegate->OnDraw();
	}
	else if(++m_draw_jump > m_low_frame_rate)
	{
		m_delegate->OnDraw();
		m_draw_jump = 0;
	}

}

inline void AppIOS::launch(Zen::P2i view_size)
{
	m_delegate->OnLaunch({(float)view_size.x, (float)view_size.y});
	mSize = view_size;
}

inline void AppIOS::resize(Zen::P2i view_size)
{
	m_delegate->OnResize({(float)view_size.x, (float)view_size.y});
	mSize = view_size;
}

inline void AppIOS::stop()
{
	m_delegate->OnExit();
}

inline void AppIOS::pause()
{
	if(m_is_paused) return;
	m_is_paused = true;
	m_delegate->OnPause();
}

inline void AppIOS::resume()
{
	if(!m_is_paused) return;
	m_delegate->OnResume();
	m_is_paused = false;
}

inline void AppIOS::touchDown(Zen::AppTouch touch)
{
	m_delegate->OnTouchDown(touch);
}

inline void AppIOS::touchUp(Zen::AppTouch touch)
{
	m_delegate->OnTouchUp(touch);
}

inline void AppIOS::touchCancel(Zen::AppTouch touch)
{
	m_delegate->OnTouchCancel(touch);
}

inline void AppIOS::touchMove(Zen::AppTouch touch)
{
	m_delegate->OnTouchMove(touch);
}

#endif
